home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / wstr.exe / WSTR.C < prev    next >
Text File  |  1993-02-26  |  22KB  |  1,182 lines

  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include <ctype.h>
  4. #include <WStr.h>
  5. #pragma hdrstop
  6.  
  7. // copyright (c) 1992, 1993 by Paul Wheaton
  8.  
  9. //.parse
  10.  
  11. /////////  BaseString class
  12.  
  13. static char GarbageChar;
  14.  
  15. char& BaseString::operator[](int Index)
  16.   {
  17.     if (Index >= Len)
  18.       {
  19.         GarbageChar=0;
  20.         return GarbageChar;
  21.       }
  22.     return P[Index];
  23.   }
  24.  
  25.   /*
  26.  
  27.   The idea here is that if a programmer were to give an index out of range
  28.   then they won't be messing up something.  If they wrote "S[5]='X'" and S
  29.   was a string of length 2, then GarbageChar would be set to 'X' and S would
  30.   be unaffected.  "MyChar=S[5]" would result in MyChar being assigned 0.
  31.  
  32.   */
  33.  
  34. //.parse
  35.  
  36. Bool BaseString::operator==(const BaseString& S) const
  37.   {
  38.     if (Len != S.Len) return No;
  39.     int I = Len/(sizeof(int));
  40.     const int* P1 = (const int*)P;
  41.     const int* P2 = (const int*)S.P;
  42.     while (I!=0)
  43.       {
  44.         if (*P1 != *P2) return No;
  45.         P1++;
  46.         P2++;
  47.         I--;
  48.       }
  49.     I= Len%(sizeof(int));
  50.     if (I!=0)
  51.       {
  52.         const char* PP1=(const char*)P1;
  53.         const char* PP2=(const char*)P2;
  54.         while (I!=0)
  55.           {
  56.             if (*PP1 != *PP2) return No;
  57.             PP1++;
  58.             PP2++;
  59.             I--;
  60.           }
  61.       }
  62.     return Yes;
  63.   }
  64.  
  65. //.parse
  66.  
  67. void BaseString::ToLower()
  68.   {
  69.     int I = Len;
  70.     char* Q = P;
  71.     while (I--) { *Q = tolower(*Q); Q++; }
  72.   }
  73.  
  74. //.parse
  75.  
  76. void BaseString::ToUpper()
  77.   {
  78.     register int I = Len;
  79.     register char* Q = P;
  80.     while (I--) { *Q = toupper(*Q); Q++; }
  81.   }
  82.  
  83. //.parse
  84.  
  85. int BaseString::Index(char SearchChar, int StartIndex) const
  86.   {
  87.     if (StartIndex>=Len) return(NotFound);
  88.     int I=StartIndex;
  89.     while ((I<Len) && (P[I]!=SearchChar)) I++;
  90.     if (I==Len) return(NotFound);
  91.     else return(I);
  92.   }
  93.  
  94. //.parse
  95.  
  96. int BaseString::Index(const char* SearchStr, int StartIndex) const
  97.   {
  98.     if (StartIndex>=Len) return(NotFound);
  99.     char* Pos=strstr(P+StartIndex,SearchStr);
  100.     if (Pos==NULL) return NotFound;
  101.     else return int(Pos-P);
  102.   }
  103.  
  104. //.parse
  105.  
  106. int BaseString::Count(char C) const
  107.   {
  108.     int Num=0;
  109.     int I;
  110.     For(I,Len) if(P[I]==C) Num++;
  111.     return Num;
  112.   }
  113.  
  114. //.parse
  115.  
  116. void BaseString::Delete(int Index,int Length)
  117.   {
  118.     // *this=BeforeSub(Index)+FromSub(Index+Length);
  119.     int S=Index+Length;
  120.     while (S<Len)
  121.       {
  122.         P[Index]=P[S];
  123.         Index++;
  124.         S++;
  125.       }
  126.     P[Index]='\0';
  127.     Len=Index;
  128.   }
  129.  
  130. //.parse
  131.  
  132. void BaseString::DeleteLast()
  133.   {
  134.     if (Len>0)
  135.       {
  136.         Len--;
  137.         P[Len]='\0';
  138.       }
  139.   }
  140.  
  141. //.parse
  142.  
  143. void BaseString::Trim()
  144.   {
  145.     if (Len==0) return;
  146.     int I=0;
  147.     while ((P[I]==' ')&&(I<Len)) I++;
  148.     if (I>0) Delete(0,I);
  149.     if (Len==0) return;
  150.     TrimTrail();
  151.   }
  152.  
  153. //.parse
  154.  
  155. void BaseString::TrimTrailTo(char C)
  156.   {
  157.     if (Len>0)
  158.       {
  159.         Len--;
  160.         while ((P[Len]!=C)&&(Len>0)) Len--;
  161.         P[Len]='\0';
  162.       }
  163.   }
  164.  
  165. //.parse
  166.  
  167. void BaseString::TrimTrail()
  168.   {
  169.     if (Len>0)
  170.       {
  171.         Len--;
  172.         while ((P[Len]==' ')&&(Len>0)) Len--;
  173.         Len++;
  174.         P[Len]='\0';
  175.       }
  176.   }
  177.  
  178. //.parse
  179.  
  180. char BaseString::At(int Index) const
  181.   {
  182.     if (Index>=Len) return '\0';
  183.     return (P[Index]);
  184.   }
  185.  
  186. //.parse
  187.  
  188. char BaseString::Last() const
  189.   {
  190.     if (Len==0) return '\0';
  191.     else return P[Len-1];
  192.   }
  193.  
  194. ///////////  String class
  195.  
  196. //.parse
  197.  
  198. void String::ReNew(int NewCapacity)  // replaces ANSI-C realloc
  199.   {
  200.     #ifdef MAJORBBS
  201.       char* P2=(char*)malloc(NewCapacity);
  202.     #else
  203.       char* P2=new char[NewCapacity];
  204.     #endif
  205.     if (P2==NULL) FatalError("out of string mem rn");
  206.     strncpy(P2,P,NewCapacity-1);
  207.     #ifdef MAJORBBS
  208.       free(P);
  209.     #else
  210.       delete(P);
  211.     #endif
  212.     P=P2;
  213.     P[NewCapacity-1]=0;
  214.   }
  215.  
  216. void String::New()
  217.   {
  218.     #ifdef MAJORBBS
  219.       P = (char*)malloc(Alloc);
  220.     #else
  221.       P = new char[Alloc];
  222.     #endif
  223.     if (P==NULL) FatalError("out of string mem");
  224.   }
  225.  
  226.  
  227. //.parse
  228.  
  229. String::String(const char& C, int L, int Extra)
  230.   {
  231.     Len = L;
  232.     Alloc = Len + Extra + 1;
  233.     New();
  234.     register int I=Len;
  235.     P[I] = 0;
  236.     while (I) P[--I] = C;
  237.   }
  238.  
  239. //.parse
  240.  
  241. String::String(int Extra)
  242.   {
  243.     Len = 0;
  244.     Alloc = Extra + 1;
  245.     New();
  246.     *P = 0;
  247.   }
  248.  
  249. //.parse
  250.  
  251. String::String(const char* CS, int Extra)
  252.   {
  253.     Len = strlen(CS);
  254.     Alloc = Len + Extra + 1;
  255.     New();
  256.     strcpy(P,CS);
  257.   }
  258.  
  259. //.parse
  260.  
  261. String::String(const BaseString& S, int Extra)
  262.   {
  263.     Len = S.Len;
  264.     Alloc = Len + Extra + 1;
  265.     New();
  266.     strcpy(P,S.P);
  267.   }
  268.  
  269. //.parse
  270.  
  271. void String::operator=(const BaseString& S)
  272.   {
  273.     if (P == S.P) return;
  274.     Len = S.Len;
  275.     if (Len >= Alloc)
  276.       {
  277.         #ifdef MAJORBBS
  278.           free(P);
  279.         #else
  280.           delete(P);
  281.         #endif
  282.         Alloc = S.Alloc;
  283.         New();
  284.       }
  285.     strcpy(P,S.P);
  286.   }
  287.  
  288. //.parse
  289.  
  290. void String::operator=(const char* CS)
  291.   {
  292.     Len = strlen(CS);
  293.     if (Len >= Alloc)
  294.       {
  295.         Alloc = Len + DefaultStringExtra + 1;
  296.         #ifdef MAJORBBS
  297.           free(P);
  298.         #else
  299.           delete(P);
  300.         #endif
  301.         New();
  302.       }
  303.     strcpy(P,CS);
  304.   }
  305.  
  306. //.parse
  307.  
  308. void String::operator=(const char C)
  309.   {
  310.     Len=1;
  311.     P[0]=C;
  312.   }
  313.  
  314. //.parse
  315.  
  316. String String::operator+(const String40& S) const
  317.   {
  318.     String T(Len+S.Len+1);
  319.     strcpy(T.P,P);
  320.     strcpy(&(T.P[Len]), S.P);
  321.     T.Len = Len+S.Len;
  322.     return(T);
  323.   }
  324.  
  325. //.parse
  326.  
  327. String String::operator+(const String120& S) const
  328.   {
  329.     String T(Len+S.Len+1);
  330.     strcpy(T.P,P);
  331.     strcpy(&(T.P[Len]), S.P);
  332.     T.Len = Len+S.Len;
  333.     return(T);
  334.   }
  335.  
  336. //.parse
  337.  
  338. String String::operator+(const String& S) const
  339.   {
  340.     String T(Len+S.Len+1);
  341.     strcpy(T.P,P);
  342.     strcpy(&(T.P[Len]), S.P);
  343.     T.Len = Len+S.Len;
  344.     return(T);
  345.   }
  346.  
  347. //.parse
  348.  
  349. String String::operator+(const char* CS) const
  350.   {
  351.     int CSLen = strlen(CS);
  352.     String T(Len+CSLen+1);
  353.     strcpy (T.P,P);
  354.     strcpy (&(T.P[Len]), CS);
  355.     T.Len = Len+CSLen;
  356.     return T;
  357.   }
  358.  
  359. //.parse
  360.  
  361. String String::operator+(char C) const
  362.   {
  363.     String S(*this,1);
  364.     S.P[Len]=C;
  365.     S.Len++;
  366.     S.P[S.Len]=0;
  367.     return S;
  368.   }
  369.  
  370. //.parse
  371.  
  372. String operator+(const String40& SS, const String& S)
  373.   {
  374.     String T(SS.Length()+S.Len+1);
  375.     strcpy(T.P,(const char*)SS);
  376.     strcpy(&(T.P[SS.Length()]), S.P);
  377.     T.Len = SS.Length()+S.Len;
  378.     return(T);
  379.   }
  380.  
  381. //.parse
  382.  
  383. String operator+(const String120& SS, const String& S)
  384.   {
  385.     String T(SS.Length()+S.Len+1);
  386.     strcpy(T.P,(const char*)SS);
  387.     strcpy(&(T.P[SS.Length()]), S.P);
  388.     T.Len = SS.Length()+S.Len;
  389.     return(T);
  390.   }
  391.  
  392. //.parse
  393.  
  394. String operator+(const char* CS, const String& S)
  395.   {
  396.     int CSLen=strlen(CS);
  397.     String T(int(CSLen+S.Len+1));
  398.     strcpy(T.P,CS);
  399.     strcpy(&(T.P[CSLen]),S.P);
  400.     T.Len = CSLen + S.Len;
  401.     return T;
  402.   }
  403.  
  404. //.parse
  405.  
  406. String operator+(char C, const String& S)
  407.   {
  408.     int NewLen=S.Len+1;
  409.     String T(NewLen);
  410.     T.P[0]=C;
  411.     strcpy(&(T.P[1]),S.P);
  412.     T.Len = NewLen;
  413.     return T;
  414.   }
  415.  
  416. //.parse
  417.  
  418. void String::operator+=(const BaseString& S)
  419.   {
  420.     if (S.Len==0) return;
  421.     int NewLen=Len+S.Len;
  422.     if (Alloc <= NewLen)
  423.       {
  424.         Alloc = NewLen+1;
  425.         ReNew(Alloc);
  426.       }
  427.     strcpy(&P[Len],S.P);
  428.     Len += S.Len;
  429.   }
  430.  
  431. //.parse
  432.  
  433. void String::operator+=(const char* CS)
  434.   {
  435.     int CSLen = strlen(CS);
  436.     if (CSLen==0) return;
  437.     int NewLen=Len+CSLen;
  438.     if (Alloc <= NewLen)
  439.       {
  440.         Alloc = NewLen+1;
  441.         ReNew(Alloc);
  442.       }
  443.     strcpy(&(P[Len]),CS);
  444.     Len += CSLen;
  445.   }
  446.  
  447. void String::operator+=(char C)
  448.   {
  449.     *this=*this+C;
  450.     /*
  451.     if (Alloc < Len+2)
  452.       {
  453.         Alloc += (DefaultStringExtra+1);
  454.         ReNew(Alloc);
  455.       }
  456.     P[Len]=C;
  457.     Len++;
  458.     P[Len]=0;
  459.     */
  460.   }
  461.  
  462. //.parse
  463.  
  464. void String::Left(int NewSize)
  465.   {
  466.     if (Len>NewSize)
  467.       {
  468.         Len=NewSize;
  469.         P[